package com.iiot.stream.main;

import com.iiot.stream.tools.DeviceStatusLengthStatistic;
import com.iiot.stream.tools.RedisMonthGatherByDid;
import com.iiot.stream.tools.RedisToMysqlDeviceRate;
import org.apache.log4j.Logger;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.CronTriggerImpl;

import java.text.ParseException;
import java.util.Timer;

/**
 * 本类实现：
 *  redis中时长数据按月汇总；
 *  汇总redis中超过10分钟的数据；
 *  MySQL中事件和状态切换。
 * @author dzm
 * @create 2018-06-15-14:21
 */
public class RedisAndMysqlMain {
    private static Logger logger = Logger.getLogger(RedisAndMysqlMain.class);
    public static void main(String[] args) {
        try {
            if (args.length != 0 && args[0] != null && !args[0].isEmpty()) {
                System.setProperty("htiiot.zookeeper",args[0]);
            }
            System.setProperty("HADOOP_USER_NAME","hdfs");
            // 按月汇总redis中设备时长
            redisMonthGatherMonitor();
            // 监控超10分钟无数据设备的代码
            deviceStatusLengthStatisticMonitor();
            // 同步前一天设备状态时长到thing_device_rate表
            deviceStatusLengthUpdateToRateMonitor();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 每月第三天合并每台设备上个月的状态时长
    public static void redisMonthGatherMonitor() throws ParseException, SchedulerException {
        logger.info("----------开始按月合并设备状态时长监控代码----------");
        // 创建TimeTask定时任务
        JobDetailImpl jobDetail = new JobDetailImpl();
        jobDetail.setName("redisMonthGatherForDid");
        jobDetail.setJobClass(RedisMonthGatherByDid.class);
        // 创建任务计划
        CronTriggerImpl trigger = new CronTriggerImpl();
        trigger.setName("redisMonthGatherForDid");
        trigger.setCronExpression("0 0 0 3 * ?");
        Scheduler sched = new StdSchedulerFactory().getScheduler();
        sched.scheduleJob(jobDetail, trigger);
        sched.start();
    }

    // 每分钟调度一次，统计设备超过10分钟没有数据的状态时长和切换mysql中的设备状态
    public static void deviceStatusLengthStatisticMonitor(){
        logger.info("------开始统计超过10分钟的设备状态时长监控代码-------");
        // 创建TimeTask定时任务
        Timer timer = new Timer();
        /**
         * 定时每隔一分钟执行一次
         * 不使用任务调度原因：如果启动两个相同代码，离线时长可能会被累加两次
         */
        timer.schedule(new DeviceStatusLengthStatistic(),0,60000);
    }

    // 每天的00：01分开始调度，将redis中前一天的设备各状态下的时长同步到mysql中
    public static void deviceStatusLengthUpdateToRateMonitor() throws ParseException, SchedulerException {
        logger.info("------------开始同步设备状态时长监控代码------------");
        // 创建TimeTask定时任务
        JobDetailImpl jobDetail = new JobDetailImpl();
        jobDetail.setName("deviceStatusLengthUpdateToRate");
        jobDetail.setJobClass(RedisToMysqlDeviceRate.class);
        // 创建任务计划
        CronTriggerImpl trigger = new CronTriggerImpl();
        trigger.setName("deviceStatusLengthUpdateToRate");
        trigger.setCronExpression("0 01 0 * * ?");
        Scheduler sched = new StdSchedulerFactory().getScheduler();
        sched.scheduleJob(jobDetail, trigger);
        sched.start();
    }
}
